#ifndef FF05C52A_FFD2_4C21_A28E_286B8659C4C2
#define FF05C52A_FFD2_4C21_A28E_286B8659C4C2

#endif /* FF05C52A_FFD2_4C21_A28E_286B8659C4C2 */

#include "head.h"

#define SIZE 1024
#define LogFile "log.txt"

enum Mes
{
    Info,
    Debug,
    Warning,
    Error,
    Fatal
};

enum Show
{
    Screen = 1,
    Onefile,
    Classfile
};

class Log
{
public:
    Log()
    {
        printMethod = Show::Screen;
        path = "./log/";
    }

    void Enable(int method)
    {
        printMethod = method;
    }

    string LevelToString(int level)
    {
        switch (level)
        {
        case Info:
            return "Info";
            break;
        case Debug:
            return "Debug";
            break;
        case Warning:
            return "Warning";
            break;
        case Error:
            return "Error";
            break;
        case Fatal:
            return "Fatal";
            break;
        default:
            return "None";
            break;
        }
    }

    void printLog(int level, const string &logtxt)
    {
        switch (printMethod)
        {
        case Screen:
            cout << logtxt << endl;
            break;
        case Onefile:
            printOnefile(LogFile, logtxt);
            break;
        case Classfile:
            printClassfile(level, logtxt);
            break;
        default:
            break;
        }
    }

    void printOnefile(const string& logname, const string& logtxt)
    {
        string logname_ = path + logname;
        int fd = open(logname_.c_str(), O_CREAT | O_WRONLY | O_APPEND, 0666);   
        if(fd < 0) return;
        write(fd, logtxt.c_str(), logtxt.size());
        close(fd);
    }

    void printClassfile(int level, const string& logtxt)
    {
        string filename = LogFile;
        filename += ".";
        filename += LevelToString(level);   // "log.txt.Debug/.."
        printOnefile(filename, logtxt);
    }

    void operator()(int level, const char* format, ...)
    {
        time_t t = time(nullptr);
        struct tm* ctime = localtime(&t);
        char leftbuffer[SIZE];
        snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", 
            LevelToString(level).c_str(), ctime->tm_year+1900, ctime->tm_mon+1,
            ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

        va_list s;
        va_start(s, format);
        char rightbuffer[SIZE];
        vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
        va_end(s);

        // 格式：默认部分+自定义部分
        char logtxt[SIZE*2];
        snprintf(logtxt, sizeof(logtxt), "%s %s", leftbuffer, rightbuffer);

        printLog(level, logtxt);
    }

    ~Log()
    {
    }

private:
    int printMethod;
    string path;
};